home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: RAVEcache.cpp
- *
- * Description: This program shows how to use RAVE to
- * render to an offscreen pixMap, which can
- * be post processed before being BLIT to a
- * window using CopyBits(). The approach is
- * essentially the following:
- *
- * 1. create a RAVE cache context (using
- * the 'kQAContext_Cache' flag)
- * 2. register a callback to be called
- * when rendering to cache context is
- * finished
- * 3. render to cache context and call
- * render end, which will trigger
- * callback.
- * 4. in callback handler, do any desired
- * postprocessing of the rendered buffer
- * and then wrap the buffer up as a pixMap
- * and copy to any window using CopyBits()
- *
- * Author: Chris Bentley 5/5/97
- *
- * Trade secret of ATI Technologies, Inc.
- * Copyright 1997, ATI Technologies, Inc., (unpublished)
- *
- * All rights reserved. This notice is intended as a precaution against
- * inadvertent publication and does not imply publication or any waiver
- * of confidentiality. The year included in the foregoing notice is the
- * year of creation of the work.
- */
- /****************************************************************/
- /* headers */
- /****************************************************************/
- #include "stdio.h"
- #include "stdlib.h"
- #include "string.h"
- #include "Quickdraw.h"
- #include "RAVE.h"
-
- /****************************************************************/
- /* defines */
- /****************************************************************/
- #define SetGV( v, _x, _y, _z, _invW, _a, _r, _g, _b ) \
- { \
- (v).x = (_x); \
- (v).y = (_y); \
- (v).z = (_z); \
- (v).invW = (_invW); \
- (v).a = (_a); \
- (v).r = (_r); \
- (v).g = (_g); \
- (v).b = (_b); \
- }
-
- /****************************************************************/
- /* typedefs */
- /****************************************************************/
- typedef unsigned short UINT16;
- typedef unsigned long UINT32;
-
- /****************************************************************/
- /* prototypes */
- /****************************************************************/
- void Initialize( void );
- int InitWindow( void );
- int InitRAVE( void );
- TQAEngine *FindEngine( TQADevice *device );
- void Cleanup( void );
- void callBack( const TQADrawContext *, const TQADevice *, const TQARect *, void *);
- PixMapHandle alloc_pixmap( UINT32 );
- void set_pixmap( PixMapHandle, UINT32, UINT32, UINT32, UINT32, void * );
-
- /****************************************************************/
- /* global variables */
- /****************************************************************/
- /*
- * Window variables
- */
- Rect winRect = {40, 40, 240, 240};
- WindowPtr winPtr;
-
- /*
- * RAVE variables
- */
- GDHandle gGDevice;
- TQADevice gDevice;
- TQAEngine *gEngine;
- TQADrawContext *gCacheContext;
- TQAVGouraud GVerts[3];
- TQARect gRect;
- TQANoticeMethod gNotice;
-
- /****************************************************************/
- /* code */
- /****************************************************************/
- /*
- * Function: main()
- *
- */
- void main( void )
- {
- /*
- * setup Mac Toolbox
- */
- Initialize();
-
- /*
- * open window
- */
- if( !InitWindow() )
- return;
-
- /*
- * init RAVE engine
- */
- if( !InitRAVE() )
- {
- Cleanup();
- return;
- }
-
- /*
- * create a cache context
- */
- if( QADrawContextNew(&gDevice,&gRect,0,gEngine,kQAContext_Cache,&gCacheContext) != kQANoErr )
- {
- printf( "ERROR: Context create failed\n" );
- Cleanup();
- return;
- }
-
- QASetFloat( gCacheContext, kQATag_ColorBG_a, 1.0 );
- QASetFloat( gCacheContext, kQATag_ColorBG_r, 0.2 );
- QASetFloat( gCacheContext, kQATag_ColorBG_g, 0.1 );
- QASetFloat( gCacheContext, kQATag_ColorBG_b, 0.4 );
-
- /*
- * register callback to be called at render end
- */
- gNotice.bufferNoticeMethod = callBack;
- QASetNoticeMethod( gCacheContext, kQAMethod_BufferComposite, gNotice, NULL );
-
- /*
- * render one triangle
- */
- QARenderStart( gCacheContext, NULL, NULL);
-
- // x y z invW a r g b
- SetGV( GVerts[0], 10.0, 10.0,10.0,1.0, 0.5, 1.0, 0.0, 0.0 );
- SetGV( GVerts[1], 150.0,10.0,10.0,1.0, 0.2, 0.0, 0.8, 0.0 );
- SetGV( GVerts[2], 75.0,100.0,10.0,1.0, 0.1, 0.0, 0.0, 0.7 );
- QADrawTriGouraud(gCacheContext, &GVerts[0], &GVerts[1], &GVerts[2], kQATriFlags_None );
-
- QARenderEnd( gCacheContext, NULL );
-
- /*
- * end
- */
- Cleanup();
- }
-
- /*
- * Function: callBack()
- *
- */
- void callBack( const TQADrawContext *drawContext, /* Draw context */
- const TQADevice *buffer, /* TQADevice describing back buffer */
- const TQARect *dirtyRect, /* Minimum area to process; NULL means whole buffer */
- void *refCon )
- {
- long rowBytes = buffer->device.memoryDevice.rowBytes;
- TQAImagePixelType pixelType = buffer->device.memoryDevice.pixelType;
- long width = buffer->device.memoryDevice.width;
- long height = buffer->device.memoryDevice.height;
- void *baseAddr = buffer->device.memoryDevice.baseAddr;
- UINT32 pixSize = (pixelType == kQAPixel_ARGB32) ? 32 : 16;
- Rect srcBounds;
- PixMapHandle hSrcPix;
- UINT32 i, x, y;
-
- /*
- * mess with the pixMap memory
- */
- if( pixSize == 16 )
- {
- UINT16 *dataPtr = (UINT16 *)baseAddr;
-
- for( i = 0; i < 100; i++ )
- {
- x = Random()%width;
- y = Random()%height;
-
- *(dataPtr+(y*width)+x) = 0xFFFFFFFF;
- }
- }
- else
- {
- UINT32 *dataPtr = (UINT32 *)baseAddr;
-
- for( i = 0; i < 100; i++ )
- {
- x = Random()%width;
- y = Random()%height;
-
- *(dataPtr+(y*width)+x) = 0xFFFF;
- }
- }
-
- /*
- * wrap kQADeviceMemory in PixMap and use
- * CopyBits() to BLIT to window
- */
- if( (hSrcPix = alloc_pixmap( pixSize )) == NULL )
- return;
-
- set_pixmap( hSrcPix, rowBytes, width, height, pixSize, baseAddr );
- SetRect( &srcBounds, 0, 0, width, height );
-
- ForeColor( blackColor );
- BackColor( whiteColor );
-
- SetPort( winPtr );
-
- CopyBits( (BitMap *)*hSrcPix,
- (BitMap *)(*(((CGrafPtr)winPtr)->portPixMap)),
- &srcBounds,
- &winPtr->portRect,
- srcCopy,
- NULL );
-
- DisposePixMap( hSrcPix );
- }
-
- /*
- * Function: alloc_pixmap()
- *
- */
- PixMapHandle alloc_pixmap( UINT32 u32depth )
- {
- PixMapHandle hPixMap;
- CTabHandle hcTab;
-
- if( (hPixMap = NewPixMap()) == NULL )
- return( NULL );
-
- hcTab = (CTabHandle)NewHandleClear( 8L );
- (*hcTab)->ctSeed = u32depth;
- (*hcTab)->ctFlags = 0x0000;
-
- DisposeHandle( (char **)(*hPixMap)->pmTable );
- (*hPixMap)->pmTable = hcTab;
-
- return( hPixMap );
- }
-
- /*
- * Function: set_pixmap()
- *
- */
- void set_pixmap( PixMapHandle pix_hdl, UINT32 rowBytes, UINT32 u32width, UINT32 u32height, UINT32 u32depth, void *data )
- {
- SetRect( &(**pix_hdl).bounds, 0, 0, u32width, u32height );
- (**pix_hdl).pixelSize = u32depth;
- (**pix_hdl).rowBytes = rowBytes | 0x8000;
- (**pix_hdl).baseAddr = (Ptr)data;
-
- (**pix_hdl).pixelType = 16; /* Direct Pixel Type (i.e. non-indexed)*/
- (**pix_hdl).cmpCount = 3;
- (**pix_hdl).cmpSize = ( (u32depth == 32) ? 8 : 5 );
-
- (**pix_hdl).packType = 0;
- (**pix_hdl).packSize = 0;
- (**pix_hdl).planeBytes = 0L;
- (**pix_hdl).pmTable = NULL;
-
- (**pix_hdl).pmVersion = 0;
- }
-
- /*
- * Function: Initialize()
- *
- */
- void Initialize( void )
- {
- OSErr error;
- SysEnvRec theWorld;
-
- /*
- * Test the computer to be sure we can do color.
- * If not we would crash, which would be bad.
- * If we can’t run, just beep and exit.
- */
- error = SysEnvirons( 1, &theWorld );
- if( theWorld.hasColorQD == false )
- ExitToShell();
-
- /*
- * Initialize all the needed managers.
- */
- InitGraf( &qd.thePort );
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- GetDateTime((unsigned long*) &qd.randSeed);
- }
-
- /*
- * Function: InitWindow()
- *
- */
- int InitWindow( void )
- {
- if( (winPtr = NewCWindow( NULL, &winRect, "\pRAVE", true,
- noGrowDocProc, (WindowPtr)-1, false, 0 )) == NULL )
- {
- printf( "ERROR: opening window\n" );
- return( false );
- }
-
- return( true );
- }
-
- /*
- * Function: InitRAVE()
- *
- */
- int InitRAVE( void )
- {
- if( (gGDevice = GetMainDevice()) == NULL )
- {
- printf( "ERROR: No monitors found\n" );
- return( false );
- }
-
- gDevice.deviceType = kQADeviceGDevice;
- gDevice.device.gDevice = gGDevice;
-
- if( (gEngine = FindEngine( &gDevice )) == NULL )
- {
- printf( "ERROR: No Engine available\n" );
- return( false );
- }
-
- if( QAEngineCheckDevice( gEngine, &gDevice ) )
- {
- printf( "ERROR: EngineCheckDevice failed\n" );
- return( false );
- }
-
- gRect.left = winRect.left; gRect.right = winRect.right;
- gRect.top = winRect.top; gRect.bottom = winRect.bottom;
-
- return( true );
- }
-
- /*
- * Function: FindEngine()
- *
- */
- TQAEngine *FindEngine( TQADevice *device )
- {
- TQAEngine *tmpEngine;
- UINT32 vendorID;
-
- /*
- * try to find ATI RAVE engine
- */
- for( tmpEngine = QADeviceGetFirstEngine(device);
- tmpEngine;
- tmpEngine = QADeviceGetNextEngine(device, tmpEngine) )
- {
- QAEngineGestalt( tmpEngine, kQAGestalt_VendorID, &vendorID );
- if( vendorID == 1 )
- return( tmpEngine );
- }
-
- /*
- * if no ATI RAVE engine, go with first engine available
- */
- return( QADeviceGetFirstEngine(device) );
- }
-
- /*
- * Function: Cleanup()
- *
- */
- void Cleanup( void )
- {
- while( !Button() )
- ;
-
- if( gCacheContext )
- QADrawContextDelete( gCacheContext );
-
- if( winPtr )
- DisposeWindow( winPtr );
- }
-